package com.hd.trans.ui.activity.customize

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.TransitionDrawable
import android.media.MediaPlayer
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.text.TextUtils
import android.view.View
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.hd.trans.R
import com.hd.trans.TranslationInterior
import com.hd.trans.TranslationUI
import com.hd.trans.binding.visible
import com.hd.trans.callback.OnCompletionListener
import com.hd.trans.common.Constants
import com.hd.trans.common.Constants.VOICE_NORMAL
import com.hd.trans.common.Constants.VOICE_RECOGNIZING
import com.hd.trans.common.Constants.VOICE_RECORD_PAUSE
import com.hd.trans.common.interf.VoiceComposeListener
import com.hd.trans.databinding.ActivitySimulTranslateBinding
import com.hd.trans.db.DataBaseMgr
import com.hd.trans.db.bean.HuDunLanguage
import com.hd.trans.db.bean.TranslateRecord
import com.hd.trans.dialog.SimuRecordingSettingPopup
import com.hd.trans.extension.observe
import com.hd.trans.flagremote.FlagRemoteCore
import com.hd.trans.flagremote.SizeRemote
import com.hd.trans.framework.click.XClickUtil.isLimitedExecute
import com.hd.trans.framework.dialog.LanguageDialog
import com.hd.trans.framework.dialog.LanguageDialogType
import com.hd.trans.homefun.EventCode
import com.hd.trans.homefun.RecordType
import com.hd.trans.limit4Use.LimitUseListener
import com.hd.trans.network.PreferenceMgr
import com.hd.trans.network.bean.AudioSourceSettings
import com.hd.trans.network.bean.TransSubsection
import com.hd.trans.network.bean.TransSubsectionSet
import com.hd.trans.network.component.HdTranslateComponent
import com.hd.trans.network.component.TranslateCallback
import com.hd.trans.ui.base.BaseFragment
import com.hd.trans.ui.base.LimitBaseActivity
import com.hd.trans.ui.component.HdRecognitionComponent
import com.hd.trans.ui.component.RecognitionCallBack
import com.hd.trans.ui.component.RecordFileCallback
import com.hd.trans.ui.fragment.SimulMergeFragment
import com.hd.trans.ui.fragment.SimulSplitFragment
import com.hd.trans.ui.model.VoiceTransViewModel
import com.hd.trans.utils.AudioManagerWrapper
import com.hd.trans.utils.LogUtil
import com.hd.trans.utils.NotificationUtil
import com.hd.trans.utils.RecordFileCallbackImpl
import com.hd.trans.utils.ToastUtils
import com.hd.trans.utils.TrackerForTrans
import com.hd.trans.utils.VoicePlayUtil
import com.hd.trans.utils.preference.Preferences
import com.hd.trans.widgets.VoicePlayView
import com.hd.trans.widgets.views.floatwindow.apply.OnFloatClickListener
import com.hd.trans.widgets.views.floatwindow.apply.SimultaneousFloatWindow
import com.hd.trans.widgets.views.floatwindow.component.ShowType
import com.lyc.speechtranscriber.bean.HdAudioSource
import com.lyc.speechtranscriber.bean.MediaProjectionProvider
import java.util.Objects
import java.util.Timer
import java.util.TimerTask

class SimulTranslateActivity: LimitBaseActivity() {
    private var isAutoPlay: Boolean = false
    private var isPauseStateCache: Boolean = false
    private var lastSaveTaskId: String = ""
    private var mFloatWindow: SimultaneousFloatWindow? = null
    private var startRecordingRunnable: Runnable? = null
    /** 是否正在请求录屏权限 */
    private var requestMediaProjectionIng = false
    /** 音频源设置 */
    val audioSourceSettings = AudioSourceSettings()
    var recordingDuration: Long = 0L
    var isRotate: Boolean = false
    private var mMediaProjectionProvider: MediaProjectionProvider? = null
    private var mCurrentViewVoice: VoicePlayView? = null
    /** 段落列表 */
    private val mSubsectionSet = TransSubsectionSet()
    private var mAudioSource = HdAudioSource.MIC

    /**
     * 停止录音的时间戳，防止点击过快
     */
    private var mStopRecordTimeMillis: Long = 0

    private lateinit var mDataBinding: ActivitySimulTranslateBinding
    lateinit var mViewModel: VoiceTransViewModel
    /** 是否允许保存录音 */
    var isAllowSaveRecording: Boolean
        get() = PreferenceMgr.getInstance().isAllowSaveChecked
        private set(value) {
            PreferenceMgr.getInstance().isAllowSaveChecked = value
        }

    private val fragmentSplit by lazy {
        SimulSplitFragment()
    }
    private val fragmentMerge by lazy {
        SimulMergeFragment()
    }

    val mAudioManager by lazy {
        AudioManagerWrapper(this)
    }

    private val mSimuRecordingSettingPopup by lazy {
        SimuRecordingSettingPopup(this@SimulTranslateActivity).apply {
            onSure = { isRecordMic,isRecordSys ->
                setAudioSource(isRecordMic,isRecordSys)
            }
        }
    }

    /**独立处理录音文件*/
    private val mRecordFileCallbackImpl by lazy {
        RecordFileCallbackImpl()
    }

    /**语音识别组件*/
    private val mRecognitionComponent by lazy {
        HdRecognitionComponent(this,true,object : RecordFileCallback {
            override fun createRecordFile(taskId: String) {
                if (mRecordFileCallbackImpl.currentTaskId.isEmpty()){
                    mRecordFileCallbackImpl.currentTaskId = taskId
                }

                val mTaskId = if (isPauseStateCache) mRecordFileCallbackImpl.currentTaskId else taskId
                if(isAllowSaveRecording && !isPauseStateCache){
                    mRecordFileCallbackImpl.createRecordFile(taskId)
                }

                if (!isPauseStateCache) {
                    mSubsectionSet.createNextSubsection(mTaskId, mViewModel.isFromLang())
                }
            }
            override fun writeByteToFile(bytes: ByteArray) {
                mRecordFileCallbackImpl.writeByteToFile(bytes)
            }
            override fun savePcmToWav(taskId: String) {
                mRecordFileCallbackImpl.savePcmToWav(taskId)
            }
        })
    }

    /**翻译组件*/
    private val mTranslateComponent by lazy {
        HdTranslateComponent(this)
    }

    /**tts播报组件*/
    private val voicePlayUtil by lazy {
        VoicePlayUtil.getInstance().apply {
            setOnCompletionListener(MediaPlayer.OnCompletionListener { mCurrentViewVoice?.stopPlay() })
        }
    }

    companion object {

        @JvmStatic
        fun open(context: Context, listener: LimitUseListener? = null) {
            limitListener = listener
            val intent = Intent(context, SimulTranslateActivity::class.java)
            context.startActivity(intent)
        }
    }

    override val pageType: EventCode
        get() = EventCode.SIMUL_TRANSLATE

    override fun getLayoutId(): Int {
        return R.layout.activity_simul_translate
    }

    override fun onResume() {
        super.onResume()
        updateFreeExperienceLayout()
        mFloatWindow?.hidden()
    }

    override fun onPause() {
        super.onPause()
        stopPlaying()

        mXHandler.postDelayed({
            if (mFloatWindow?.isShowing == true || requestMediaProjectionIng){
                // 如果显示了悬浮窗
                // 或者正在请求录屏权限
                // 不停止录音
            }
            else{
                if (mViewModel.isRecording()){
                    pauseRecording()
                }
            }
        }, 300)
    }

    override fun onDestroy() {
        super.onDestroy()
        mRecordFileCallbackImpl.release()
        mFloatWindow?.remove()
        mAudioManager.releaseAll()
    }

    override fun onBackPressed() {
        val betterFragment: BaseFragment? = getContentFragment()
        if (betterFragment != null) {
            if (betterFragment.onBackPressed()) {
                return
            }
        }
        if (mViewModel.isRecording()){
            stopRecording()
        }else{
            super.onBackPressed()
        }
    }

    override fun initViewsAndEvents(savedInstanceState: Bundle?) {
        super.initViewsAndEvents(savedInstanceState)
        mDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_simul_translate)
        mViewModel = ViewModelProvider(this).get(VoiceTransViewModel::class.java)

        mSubsectionSet.onDataItemChanged = { data,index->
            mXHandler.post {
                displaySubsection(data)
            }
        }

        observe()
        initView()
        initData()
        NotificationUtil.getInstance().checkNotification(this)
    }

    private fun observe() {
        observe(mViewModel.languageFrom) {
            mDataBinding.tvLangFrom.text = it.name
            mDataBinding.ivFlagLeft.imageTintList = null
            FlagRemoteCore.loadFlagDrawable(mDataBinding.ivFlagLeft, it.translateCode, SizeRemote.W225)
        }

        observe(mViewModel.languageTo) {
            mDataBinding.tvLangTo.text = it.name
            mDataBinding.ivFlagRight.imageTintList = null
            FlagRemoteCore.loadFlagDrawable(mDataBinding.ivFlagRight, it.translateCode, SizeRemote.W225)
        }
        observe(mViewModel.operateLanguage) {
        }
        observe(mViewModel.voiceState) {
            updateVoiceState(it)
        }
        observe(mViewModel.isFromLang){
            mDataBinding.ivStatusLeft.visible = it
            mDataBinding.ivStatusRight.visible = !it
        }
    }

    private fun initView() {
        mDataBinding.apply {
            click = this@SimulTranslateActivity

            val isSplitScreen = Preferences.isSplitScreen
            mDataBinding.rbSplitScreen.isChecked = isSplitScreen
            mDataBinding.rbMergeScreen.isChecked = !isSplitScreen
            rgSplitWordTop.setOnCheckedChangeListener { _, checkedId ->
                when(checkedId){
                    R.id.rb_split_screen -> {
                        Preferences.isSplitScreen = true
                    }
                    R.id.rb_merge_screen -> {
                        Preferences.isSplitScreen = false
                    }
                }
                changeScreenUI()
            }
        }
    }

    private fun initData() {
        val fromLangName = PreferenceMgr.getInstance().translatePreference.voiceFromLanguage
        val toLangName = PreferenceMgr.getInstance().translatePreference.voiceToLanguage
        mViewModel.languageFrom.value = DataBaseMgr.getInstance().getLanguageByName(fromLangName)
        mViewModel.languageTo.value = DataBaseMgr.getInstance().getLanguageByName(toLangName)

        mViewModel.voiceState.value = VOICE_NORMAL
        changeScreenUI()
        if (isAndroid10Higher()) {
            //如果手机系统为安卓10以上

            //监听耳机连接
            mAudioManager.setDevicesListener {
                getContentFragment()?.onDevicesConnect(it)
            }

        }
    }

    /**
     * 全屏/分屏
     */
    val mTabName: String
        get() = if(Preferences.isSplitScreen) "分屏" else "全屏"

    private fun updateFreeExperienceLayout(){
        val isVip = isVip()
        mDataBinding.llFreeExperience.isVisible = !isVip
        if (!isVip){
            updateFreeTime()
        }
    }

    @SuppressLint("SetTextI18n")
    private fun updateFreeTime(){
        mDataBinding.tvFreeTime.post {
            val time: Int = Math.ceil((Preferences.simulTransFreeTime.getFreeTime()).toDouble()).toInt()
            if (time == 0){
                if (mViewModel.isRecording()){
                    startAndStop()
                }
                mDataBinding.tvFreeExperience.text = "非VIP体验"
                mDataBinding.tvFreeTime.text = "1分钟已结束"
                mDataBinding.tvFreeTime.setTextColor(Color.parseColor("#3080F9"))
                Preferences.simulTransFreeTime = Preferences.simulTransFreeTime.consumeAllFreeTime()

                /*if (mFloatWindow?.isShowing == true){
                    isFormFreeFinish = true
                    RouterUtils.backToApp(mActivity)
                }
                else{
                    ToastUtils.showNormal("体验时间已结束")
                    mDataBinding.tvFreeTime.postDelayed({
                        intercept(false, "同声传译-非VIP试用")
                    },600) //延迟600毫秒，让用户先看到toast
                }*/

                ToastUtils.showNormal("体验时间已结束")
                mDataBinding.tvFreeTime.postDelayed({
                    intercept(false, "同声传译-非VIP试用")
                },600) //延迟600毫秒，让用户先看到toast
            }
            else{
                mDataBinding.tvFreeExperience.text = if (mViewModel.isRecording()) "非VIP正在体验同声传译" else "非VIP体验同声传译"
                mDataBinding.tvFreeTime.setTextColor(Color.parseColor(if (time > 10) "#3080F9" else "#F3554E"))
                if (time > 59){
                    mDataBinding.tvFreeTime.text = "${time / 60}分钟"
                }
                else{
                    mDataBinding.tvFreeTime.text = "${time}s"
                }
            }

        }
    }

    /**
     * 更新语音状态
     */
    private fun updateVoiceState(state: Int) {
        when(state){
            VOICE_NORMAL -> {
            }
            VOICE_RECOGNIZING -> {
                stopPlaying()
            }
            VOICE_RECORD_PAUSE -> {
            }
        }
        updateButton()
    }

    private fun onRotateChanged(isRotate: Boolean) {
        getContentFragment()?.onRotateChanged(isRotate)
    }

    /**暂停语音播报*/
    fun stopPlaying() {
        voicePlayUtil.stopPlay()
    }
    
    fun setAutoVoicePlay(isAutoPlay: Boolean){
        this.isAutoPlay = isAutoPlay
    }

    private fun getContentFragment(): BaseFragment? {
        val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
        if (fragment is BaseFragment) {
            return fragment
        }
        return null
    }

    // 在类中添加一个新方法用于渐变切换背景
    private fun setBackgroundWithTransition(drawable: Drawable) {
        // 获取当前背景
        val currentBackground = mDataBinding.root.background

        // 如果当前没有背景或与目标背景相同，则直接设置
        if (currentBackground == null || currentBackground === drawable) {
            mDataBinding.root.background = drawable
            return
        }

        // 创建TransitionDrawable来实现渐变效果
        val transitionDrawable = TransitionDrawable(arrayOf(currentBackground, drawable))

        // 设置背景
        mDataBinding.root.background = transitionDrawable

        // 开始渐变动画
        transitionDrawable.startTransition(200)
    }

    @SuppressLint("CommitTransaction", "UseCompatLoadingForDrawables")
    private fun changeScreenUI(){
        val isSplitScreen = Preferences.isSplitScreen
        //替换Fragment
        val fragment = if (isSplitScreen){
            fragmentSplit
        }else{
            fragmentMerge
        }
        supportFragmentManager.beginTransaction().replace(
            R.id.fragment_container,
            fragment
        ).commitAllowingStateLoss()
        //通知Fragment状态改变
        fragment.onStateChange()
        //状态栏颜色
        setStatusBarFontColor(!isSplitScreen)
        //背景
        val targetDrawable = if (isSplitScreen) getDrawable(R.drawable.trans_bg_simul_translate2) else getDrawable(R.drawable.trans_bg_simul_translate1)
        setBackgroundWithTransition(targetDrawable!!)
        //国旗按钮颜色
        updateButton()

        val twoColumnColor = if (isSplitScreen) Color.WHITE else Color.parseColor("#16181A")
        val buttonColorTint = ColorStateList.valueOf(twoColumnColor)
        //标题栏状态
        mDataBinding.btnBack.imageTintList = buttonColorTint
        mDataBinding.btnRotate.imageTintList = buttonColorTint
        mDataBinding.btnSetting.imageTintList = buttonColorTint
        mDataBinding.btnLanguageDialog.imageTintList = if (isSplitScreen) buttonColorTint else null
        mDataBinding.rgSplitWordTop.isSelected = isSplitScreen
        //切换按钮字体颜色、粗细
        mDataBinding.rbMergeScreen.setTextColor(Color.parseColor(if (!isSplitScreen) "#16181A" else "#E4E6EA" ))
        mDataBinding.rbSplitScreen.setTextColor(Color.parseColor(if (isSplitScreen) "#16181A" else "#93989C"))
        mDataBinding.rbMergeScreen.paint.isFakeBoldText = !isSplitScreen
        mDataBinding.rbSplitScreen.paint.isFakeBoldText = isSplitScreen
    }

    private fun updateButton() {
        if(mViewModel.isRecording()){
            //正在录音

            if (mViewModel.isFromLang()){
                mDataBinding.ivFlagLeft.setImageResource(R.drawable.trans_ic_simultaneous_stop)
                if (isAllowSaveRecording){
                    //渲染成红色
                    mDataBinding.ivFlagLeft.imageTintList = ColorStateList.valueOf(Color.RED)
                }
                else{
                    //清除渲染颜色
                    mDataBinding.ivFlagLeft.imageTintList = null
                }
                mDataBinding.ivFlagRight.imageTintList = null
                FlagRemoteCore.loadFlagDrawable(mDataBinding.ivFlagRight, mViewModel.languageTo.value!!.translateCode, SizeRemote.W225)

            } else{
                mDataBinding.ivFlagRight.setImageResource(R.drawable.trans_ic_simultaneous_stop)
                if (isAllowSaveRecording){
                    //渲染成红色
                    mDataBinding.ivFlagRight.imageTintList = ColorStateList.valueOf(Color.RED)
                }
                else{
                    //清除渲染颜色
                    mDataBinding.ivFlagRight.imageTintList = null
                }
                mDataBinding.ivFlagLeft.imageTintList = null
                FlagRemoteCore.loadFlagDrawable(mDataBinding.ivFlagLeft, mViewModel.languageFrom.value!!.translateCode, SizeRemote.W225)
            }
        }
        else{
            //没有在录音
            mDataBinding.ivFlagLeft.imageTintList = null
            mDataBinding.ivFlagRight.imageTintList = null
            FlagRemoteCore.loadFlagDrawable(mDataBinding.ivFlagLeft, mViewModel.languageFrom.value!!.translateCode, SizeRemote.W225)
            FlagRemoteCore.loadFlagDrawable(mDataBinding.ivFlagRight, mViewModel.languageTo.value!!.translateCode, SizeRemote.W225)
        }

    }

    private fun showSelectLanguageDialog(isFromLang: Boolean) {
        if(mViewModel.isRecording()){
            return
        }
        val dialog = LanguageDialog(
            Objects.requireNonNull<HuDunLanguage?>(mViewModel.languageFrom.value),
            Objects.requireNonNull<HuDunLanguage?>(mViewModel.languageTo.value),
            isFromLang, LanguageDialogType.VOICE, LanguageDialogType.TO_VOICE
        )
        dialog.show(supportFragmentManager, "LanguageDialog")
        dialog.setOnLanguageChangedListener(object : LanguageDialog.OnLanguageChangedListener{
            override fun onLanguageChanged(
                fromLanguage: HuDunLanguage,
                toLanguage: HuDunLanguage,
                selectedLanguage: HuDunLanguage
            ) {
                mViewModel.languageFrom.value = fromLanguage
                mViewModel.languageTo.value = toLanguage
                PreferenceMgr.getInstance().translatePreference
                    .saveVoiceFromLanguage(fromLanguage.name)
                PreferenceMgr.getInstance().translatePreference
                    .saveVoiceToLanguage(toLanguage.name)
            }
        })
    }

    /**停止识别*/
    fun stopRecording() {
        mStopRecordTimeMillis = System.currentTimeMillis()
        if(!mViewModel.isStop()){
            mViewModel.voiceState.value = VOICE_NORMAL
            isPauseStateCache = false
            mRecognitionComponent.stopRecognition()
            releaseTimeChronometer()
            cancelRecCountDownTimer()
            saveRecord()
        }
    }

    /**暂停语音识别*/
    private fun pauseRecording() {
        if(mViewModel.isRecording()){
            mViewModel.voiceState.value = VOICE_RECORD_PAUSE
            isPauseStateCache = true
            mRecognitionComponent.stopRecognition()
            releaseTimeChronometer()
            cancelRecCountDownTimer()
        }
    }

    /**
     * 点击语言按钮
     */
    private fun doClickLanguageButton(isLeft: Boolean, isFormUser:Boolean = true){
        mViewModel.isFromLang.value = isLeft

        if (isFormUser){
            TranslationInterior.getTrackerListener().click(
                TrackerForTrans.TSCY,
                if(mViewModel.isRecording()) "停止" else "录制",
                "录音键")
        }

        startAndStop(isFormUser)
    }

    /**
     * 开始或停止
     */
    fun startAndStop(isFormUser: Boolean = false){

        if(mViewModel.isRecording()){
            stopRecording()
        }else{
            requestAudioPermission(){
                if(!intercept(true)){
                    if(isFormUser){
                        ToastUtils.showBottom("请说${mViewModel.getHdFromLanguage()?.name}")
                    }
                    startRecording()
                }
            }
        }

    }

    /**
     * 开始或暂停
     */
    fun startAndPause(isFormUser:Boolean = false){
        if (!mViewModel.isPause()) {
            pauseRecording()
        } else {
            requestAudioPermission(){
                if(!intercept(true)){
                    if(isFormUser){
                        ToastUtils.showBottom("请说${mViewModel.getHdFromLanguage()?.name}")
                    }
                    startRecording()
                }
            }
        }
    }

    /**
     * 收音设置弹窗
     */
    fun showRecordingSettingDialog(){
        TranslationInterior.getTrackerListener().click(
            "同声传译",
            mTabName,
            "收音设置"
        )

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            //如果手机系统为安卓10以下
            ToastUtils.showNormal("需将手机系统升级为安卓10及以上")
            return
        }

        mSimuRecordingSettingPopup.show()
    }

    fun requestMediaProjection(block:((MediaProjectionProvider?)->Unit)? = null){
        if (mMediaProjectionProvider != null){
            block?.invoke(mMediaProjectionProvider!!)
            return
        }

//        if (mFloatWindow?.isShowing == true){
//            mFloatWindow?.hidden()
//        }

        requestMediaProjectionIng = true
        val mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        activityResultLauncher.launch(mediaProjectionManager.createScreenCaptureIntent(), onResult = { result->
            val resultCode = result.resultCode
            val data = result.data
            if (resultCode == Activity.RESULT_CANCELED || data == null) {
                LogUtil.d("获取录屏权限失败")
                block?.invoke(null)
            } else {
                LogUtil.d("获取录屏权限成功")
                mMediaProjectionProvider = MediaProjectionProvider(mediaProjectionManager, resultCode, data)
                block?.invoke(mMediaProjectionProvider!!)
            }
            requestMediaProjectionIng = false
        })
    }

    fun getHandler(): Handler {
        return mXHandler
    }

    fun langNameFix(name: String):String{
        return when(name){
            "中文（粤语）" -> "粤语"
            "中文（简体）",
            "中文（繁体）",
            "中文（文言文）"
            -> "中文"

            else -> name
        }
    }

    fun showFloatWindow(){
        TranslationInterior.getTrackerListener().click(
            "同声传译",
            mTabName,
            "悬浮窗口"
        )
        if(!intercept(false, "悬浮窗口")){
            requestFloatWindowPermission{
                createFloatWindow()
            }
        }
    }

    private fun createFloatWindow() {
        if(mFloatWindow == null){
            mFloatWindow = SimultaneousFloatWindow(
                this,
                packageName,
                object : OnFloatClickListener {
                    override fun showType(view: View?, type: ShowType) {
                        TranslationInterior.getTrackerListener().click(
                            "字幕浮窗",
                            "显示模式"
                        )
                    }

                    override fun setting(view: View?) {
                        TranslationInterior.getTrackerListener().click(
                            "字幕浮窗",
                            "设置"
                        )
                    }

                    override fun screenRecover(view: View?) {
                        TranslationInterior.getTrackerListener().click(
                            "字幕浮窗",
                            "跳转到同声传译"
                        )
                    }

                    override fun closeFloatWindow(view: View?) {
                        TranslationInterior.getTrackerListener().click(
                            "字幕浮窗",
                            "关闭浮窗"
                        )
                    }
                });
        }

        //显示
        mFloatWindow?.changeLang(
            mViewModel.getHdFromLanguage()?.name!!,
            mViewModel.getHdToLanguage()?.name!!
        )
        mFloatWindow?.show()
        if(!mViewModel.isRecording()){
            startAndStop()
        }

    }

    /**
     * 系统版本是否>=安卓10
     */
    fun isAndroid10Higher():Boolean{
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
    }

    fun getSubsectionSet():TransSubsectionSet{
        return mSubsectionSet
    }

    fun setAudioSource(isRecordMic:Boolean,isRecordSys:Boolean){
        mAudioSource = if (isRecordMic && isRecordSys) {
            HdAudioSource.ALL
        } else if (isRecordSys) {
            HdAudioSource.SYSTEM
        } else{
            HdAudioSource.MIC
        }

        if (isRecordSys){
            mRecognitionComponent.setMediaProjectionProvider(mMediaProjectionProvider)
        }
        mRecognitionComponent.setAudioSource(mAudioSource)
    }

    private var mTimeChronometer: Timer? = null
    private var recCountDownTimer: CountDownTimer? = null

    /**
     * 开始语音识别倒计时
     * 如果在指定时间内没有识别到内容，则停止录音
     */
    private fun startRecCountDownTimer(){
        if (recCountDownTimer != null){
            recCountDownTimer?.cancel()
            recCountDownTimer = null
        }

        //限制时间，1分钟
        val limitTime = 60000L

        recCountDownTimer = object : CountDownTimer(limitTime,limitTime) {
            override fun onTick(millisUntilFinished: Long) {}
            override fun onFinish() {
                if (mViewModel.isRecording()) {
                    stopRecording()
//                    mXHandler.post {
//                        mAutoStopTipsDialog.show()
//                    }
                }
            }
        }.start()

    }

    private fun cancelRecCountDownTimer(){
        recCountDownTimer?.cancel()
        recCountDownTimer = null
    }

    private fun startTimeChronometer(){
        releaseTimeChronometer()
        if (!mViewModel.isPause()) {
            recordingDuration = 0L
        }
        mTimeChronometer = Timer().apply {
            schedule(object : TimerTask(){
                override fun run() {
                    recordingDuration += 300
                    consumeFreeTrialTime(300, false)
                    mXHandler.post {
                        onChronometerTickListener(recordingDuration)
                    }
                }
            },0,300)
        }

    }

    private fun releaseTimeChronometer() {
        mTimeChronometer?.cancel()
        mTimeChronometer?.purge()
        mTimeChronometer = null
    }

    private fun onChronometerTickListener(durationMillis: Long) {
        getContentFragment()?.onChronometerTickListener(durationMillis)
        if (!isVip()){
            updateFreeTime()
        }
    }

    private fun updateFloatWindow() {
        var originalContent = mSubsectionSet.getCurSubsection()?.originalContent?.trim() ?: ""
        mSubsectionSet.getCurSubsection()?.msg?.let {
            originalContent += it
        }
        var translateContent = mSubsectionSet.getCurSubsection()?.translateContent?.trim() ?: ""
        mSubsectionSet.getCurSubsection()?.msg2?.let {
            translateContent += it
        }
        mFloatWindow?.changeContent(
            originalContent,
            translateContent
        )
    }

    /**
     * 开始录音，防止重复快速点击
     */
    private fun startRecording() {
        val currentTimeMillis = System.currentTimeMillis()
        var delayed = 800L - (currentTimeMillis - mStopRecordTimeMillis)
        if (delayed < 0){
            delayed = 0
        }

        startRecordingRunnable?.let {
            mXHandler.removeCallbacks(it)
        }

        startRecordingRunnable = Runnable {

            executeRecognize()

        }.apply {
            mXHandler.postDelayed(this, delayed)
        }
    }

    private fun onRecognitionChanged(msg: String, sentenceOver: Boolean, sentence: String) {
        LogUtil.d("onRecognitionChanged", msg)
        LogUtil.d("onRecognitionChanged", sentenceOver.toString())
        LogUtil.d("onRecognitionChanged", sentence)

        val taskId = mRecordFileCallbackImpl.currentTaskId

        val isTemp: Boolean
        val text: String
        val subsection = if (sentenceOver) {
            isTemp = false
            text = sentence
            mSubsectionSet.appendOrgContent(taskId, sentence, recordingDuration)
        }else{
            isTemp = true
            text = msg
            mSubsectionSet.setMsg(taskId, msg)
        }
        subsection?.let {
            executeTranslate(taskId, text, isTemp)

            onContentChange(taskId)
        }
    }

    private fun displaySubsection(data: TransSubsection) {
        getContentFragment()?.displaySubsection(data)
        updateFloatWindow()
    }

    private fun onContentChange(taskId: String) {
        getContentFragment()?.onContentChange(taskId)
        updateFloatWindow()
    }

    private fun textToSpeech(text: String, ttsCode: String) {
        voicePlayUtil.executeCompositeFile(ttsCode, text, object : VoiceComposeListener {
            override fun onStarting() {
                mCurrentViewVoice?.loading()
            }

            override fun onCompleted(file: String, isLocal: Boolean) {
                if(isAutoPlay){
                    mCurrentViewVoice?.startPlay()
                    voicePlayUtil.startPlay(file)
                }else{
                    stopPlaying()
                }
            }

            override fun onDownloadFailed() {
                mCurrentViewVoice?.loadingFailed()
                voicePlayUtil.stopPlay()
            }
        })
    }

    private fun executeTranslate(taskId: String, text: String, isTemp: Boolean) {
        if(isTemp){
            //未确定的识别内容，限制3秒执行一次翻译
            if(!isLimitedExecute(3000)){
                return
            }
        }
        if(text.isEmpty()){
            return
        }

        val fromTranslateCode = mViewModel.getHdFromLanguage()?.translateCode!!
        val toTranslateCode = mViewModel.getHdToLanguage()?.translateCode!!

        mTranslateComponent.translationText(
            text,
            fromTranslateCode,
            toTranslateCode,
            false,
            object : TranslateCallback {
                override fun onTranslateFailed(code: Int, msg: String) {
                    if (code == Constants.ResponseCode.ERROR_IS_DANGER
                        || code == Constants.ResponseCode.ERROR_COMM
                        || code == Constants.ResponseCode.ERROR_NETWORK
                    ) {
                        ToastUtils.showError(msg)
                    } else {
                        ToastUtils.showError(R.string.fanyi_faith_tip)
                    }

                    mSubsectionSet.appendTraContent(taskId,"")
                }

                override fun onTranslateCompleted(
                    data: String?,
                    fromLangCode: String,
                    toLangCode: String,
                    status: Boolean
                ) {
                    var result = data?.trim() ?: ""
                    if (result.isEmpty()){
                        ToastUtils.showNormal( R.string.fanyi_faith_tip)
                        mSubsectionSet.appendTraContent(taskId,"")
                        return
                    }
                    if (result.endsWith("\n")) {
                        val endIndex = result.lastIndexOf("\n")
                        result = result.substring(0, endIndex)
                    }

                    if (isTemp){
                        mSubsectionSet.setMsg2(taskId,result)
                    }else{
                        mSubsectionSet.appendTraContent(taskId,result)
                        this@SimulTranslateActivity.onContentChange(taskId)

                        if(isAutoPlay){
                            //播放语音
                            textToSpeech(result, mViewModel.getHdToLanguage()?.ttsCode ?: "")
                        }
                    }
                }
            }
        )
    }

    /**执行语音识别*/
    private fun executeRecognize(){
        val language: HuDunLanguage = mViewModel.getHdFromLanguage() ?: return

        if(mViewModel.voiceState.value == VOICE_RECOGNIZING){
            stopRecording()
            return
        }
        startTimeChronometer()
        startRecCountDownTimer()
        mViewModel.voiceState.value = VOICE_RECOGNIZING
        mRecognitionComponent.setMediaProjectionProvider(mMediaProjectionProvider)
        mRecognitionComponent.voiceRecognition(language, object : RecognitionCallBack {

            override fun onRecognitionFailed(msg: String?, code: Int) {
            }

            override fun onRecognitionCompleted(msg: String?, code: Int) {
                val sentence = mSubsectionSet.getCurSubsection()?.msg?: ""
                this@SimulTranslateActivity.onRecognitionChanged("", true, sentence)
            }

            override fun onRecognitionChanged(
                msg: String,
                code: Int,
                sentenceOver: Boolean,
                sentence: String
            ) {

                val sentenceTrim = sentence.trim()
                if (TextUtils.isEmpty(sentenceTrim))
                    return

                //识别到文字，说明还在说话
                startRecCountDownTimer()

                this@SimulTranslateActivity.onRecognitionChanged(msg, sentenceOver, sentence)
            }

            override fun onVoiceChanged(waveBytes: Int, readBytes: Int) {
            }

        })
    }

    private fun saveRecord() {
        if(!mViewModel.isPause()){
            mRecordFileCallbackImpl.saveAudioFile(mRecordFileCallbackImpl.currentTaskId){ wavPath ->
                val originalContent = mSubsectionSet.getCurSubsection()?.originalContent ?: ""
                val translateContent = mSubsectionSet.getCurSubsection()?.translateContent ?: ""
                if (originalContent.isNotEmpty() && translateContent.isNotEmpty()){
                    if(lastSaveTaskId != mRecordFileCallbackImpl.currentTaskId){
                        lastSaveTaskId = mRecordFileCallbackImpl.currentTaskId
                        val record = TranslateRecord()
                        record.isVoice = false
                        record.isCollected = false
                        record.languageFrom = mViewModel.getHdFromLanguage()
                        record.languageTo = mViewModel.getHdToLanguage()
                        record.contentOrig = mSubsectionSet.getCurSubsection()?.originalContent ?: ""
                        record.contentTranslate = mSubsectionSet.getCurSubsection()?.translateContent ?: ""
                        record.triggerTime = System.currentTimeMillis()
                        record.voiceFile = wavPath
                        record.recordType = RecordType.VOICE
                        DataBaseMgr.getInstance().addTranslateRecord(record)

                        mXHandler.post(Runnable { ToastUtils.showNormal("录音文件保存成功！\n请在历史记录中查看！") })
                    }
                }
            }
        }
    }

    override fun onViewClick(v: View?) {
        mDataBinding.apply {
            when(v){
                btnBack -> {
                    finish()
                }
                btnSetting -> {
                    TranslationUI.openVoiceSettingActivity(this@SimulTranslateActivity, false)
                }
                btnLanguageLeft -> {
                    mViewModel.operateLanguage.value = mViewModel.languageFrom.value
                    doClickLanguageButton(true)
                }
                btnLanguageRight -> {
                    mViewModel.operateLanguage.value = mViewModel.languageTo.value
                    doClickLanguageButton(false)
                }
                btnLanguageDialog -> {
                    showSelectLanguageDialog(true)
                }
                btnRotate -> {
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        mTabName,
                        "文字翻转"
                    )
                    isRotate = !isRotate
                    btnRotate.rotationX = if(isRotate) 180f else 0f
                    btnRotate.rotationY = if(isRotate) 180f else 0f
                    onRotateChanged(isRotate)
                }
                llFreeExperience -> {
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        mTabName,
                        "同声传译-非VIP试用立即开通"
                    )
                    intercept(false, "同声传译-非VIP试用立即开通")
                }
            }
        }
    }
}